package com.google.code.wicket.auth.component.strategy;

import org.apache.wicket.Component;
import org.apache.wicket.authorization.Action;
import org.apache.wicket.authorization.IAuthorizationStrategy;

import com.google.code.wicket.auth.component.strategy.part.DynamicAuthorizationStrategy;
import com.google.code.wicket.auth.component.strategy.part.StaticAuthorizationStrategy;

/**
 * An {@link IAuthorizationStrategy} that delegates to two different strategies,
 * {@link StaticAuthorizationStrategy} for class based authorization and
 * {@link DynamicAuthorizationStrategy} for component-based authorization.
 */
public class ComposedAuthorizationStrategy implements IAuthorizationStrategy {

    private final StaticAuthorizationStrategy staticAuthorizationStrategy;
    private final DynamicAuthorizationStrategy dynamicAuthorizationStrategy;

    /**
     * Constructor with a strategy for dynamic (runtime) component-based
     * authorization.
     * 
     * @param dynamicAuthorizationStrategy
     */
    public ComposedAuthorizationStrategy(
            final DynamicAuthorizationStrategy dynamicAuthorizationStrategy) {
        this(null, dynamicAuthorizationStrategy);
    }

    /**
     * Constructor with a strategy for static (class based) authorization.
     * 
     * @param staticAuthorizationStrategy
     */
    public ComposedAuthorizationStrategy(
            final StaticAuthorizationStrategy staticAuthorizationStrategy) {
        this(staticAuthorizationStrategy, null);
    }

    /**
     * Constructor with two strategies, one for static (class based)
     * authorization and one for dynamic (runtime) component-based
     * authorization.
     * 
     * @param staticAuthorizationStrategy
     * @param dynamicAuthorizationStrategy
     */
    public ComposedAuthorizationStrategy(
            final StaticAuthorizationStrategy staticAuthorizationStrategy,
            final DynamicAuthorizationStrategy dynamicAuthorizationStrategy) {
        super();
        this.staticAuthorizationStrategy = staticAuthorizationStrategy == null ? StaticAuthorizationStrategy.ALLOW_ALL
                : staticAuthorizationStrategy;
        this.dynamicAuthorizationStrategy = dynamicAuthorizationStrategy == null ? DynamicAuthorizationStrategy.ALLOW_ALL
                : dynamicAuthorizationStrategy;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isActionAuthorized(final Component component,
            final Action action) {
        return this.dynamicAuthorizationStrategy.isActionAuthorized(component,
                action);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <T extends Component> boolean isInstantiationAuthorized(
            final Class<T> componentClass) {
        return this.staticAuthorizationStrategy
                .isInstantiationAuthorized(componentClass);
    }

}
